home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PsL Monthly 1993 December
/
PSL Monthly Shareware CD-ROM (December 1993).iso
/
prgmming
/
dos
/
c
/
tsr_c.exe
/
MAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-24
|
8KB
|
338 lines
#pragma option -zAINIT // change code segment class to 'INIT'
// so that it comes after the stack and
// it can be released when going resident.
#pragma option -zFINIT // change far data segment class to 'INIT'
// for same reason.
#pragma option -zEINIT_DATA // also force all far data to go to one
// segment (just for this module)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <dos.h>
#include "vectors.h"
#define puts(a) jputs (a) // cause the real puts() adds a newline dammit!
#define ENDL() {if (verbose) putchar ('\n');}
char far hex_buffer[5]; // used by hex();
char far init_title[] = "JLink Version 1.0 Copyright (c) 1992 by Borland International\n";
char far init_resident[] = "TSR is resident\n";
char far init_unloaded[] = "TSR is unloaded\n";
char far init_v_psp[] = "\nPSP:";
char far init_is_loaded[] = "\aERROR: JLink is already loaded, exiting...\n";
char far init_not_loaded[] = "\aERROR: JLink is not loaded, exiting...\n";
char far init_e_unloading[] = "\aERROR: could not unload because of INT-";
char far init_bad_param[] = "\aERROR: invalid parameter: ";
char far init_hose_bad[] = "\aERROR: extream hose error!\n";
char far init_bad_speed[] = "WARNING: invalid speed selected, resetting to default.\n";
char far init_help[] =
"\nUsage: JLINK [options]\n\n"
" -? Prints this help screen\n"
// " -Ffilename Sets the filename to log to (default = test.dat)\n"
" -R Removes the TSR from memory\n"
" -Sxxx Sets the speed of updating (in 18ths sec)\n"
" -V Verbose mode (-V- quite mode)\n";
int far verbose = 1; // 0 = none, 1 = regular, 2 = extra strength
char far fname[81] = "TEST.DAT";
void _restorezero (void); // from the BORLAND startup code
int is_there (void); // see's if we are loaded already
void hook_em_danno (void); // gets ready to go resident
char *byte (BYTE); // converts a byte into a hex string
char *hex (WORD); // converts an int to a string in hex
void _hex (WORD); // helper for hex()
void jputs (char *s); // my own string printing function
int unload (void); // unload's the resident TSR (if possible)
void back_here (void); // destination of the 'DOS unload' rollercoaster
int main (int argc, char *argv[])
{
int x = 1;
WORD temp;
if (argv[1][0] != ':') // do title?
puts (init_title);
else
x = 2, verbose = 0;
for (;x < argc; x++)
{
if (argv[x][0] == '-' || argv[x][0] == '/')
{
switch (toupper (argv[x][1]))
{
case 'H':
case '?':
puts (init_help);
return 3;
case 'R':
if (unload ())
return 4;
else
return 5;
case 'V':
verbose = 2;
if (argv[x][2] == '-')
verbose = 0;
break;
case 'S':
temp = atoi (&argv[x][2]);
if (temp == 0 || temp > 255)
puts (init_bad_speed);
else
{
_8_max = temp;
}
break;
/*
case 'F':
strcpy (fname, &(argv[x][2]));
break;
*/
default: goto bad_param;
}
}
else
{
bad_param:
puts (init_bad_param);
puts (argv[x]);
ENDL();
return 2;
}
}
if (is_there ())
{
puts (init_is_loaded);
return 1;
}
else
{
if (verbose == 2)
{
puts (init_v_psp);
puts (hex (_psp));
ENDL();
}
/*
if ((file = fopen (fname, "wt")) == NULL)
{
perror (fname);
return 7;
}
*/
puts (init_resident);
hook_em_danno ();
keep(0, (_SS - _psp) + 1);
}
return 0;
}
int is_there (void)
{
_AH = MY_ID;
_AL = DETECT_CMD;
geninterrupt (0x2F);
if (_AX == 0xFFFF)
return 1;
return 0;
}
void hook_em_danno ()
{
WORD s,o;
_AH = 0x34; // UNDOC DOS get inDOS pointer
geninterrupt (0x21);
s = _ES;
o = _BX;
indos = MK_FP (s,o); // be nice to DOS so it doesn't "barf" on us.
old_8 = getvect (0x8);
old_2F = getvect (0x2F);
old_28 = getvect (0x28);
setvect (0x8, new_8);
setvect (0x2F, new_2F);
setvect (0x28, new_28);
}
char *hex (WORD x)
{
_ES = FP_SEG (hex_buffer);
_DI = FP_OFF (hex_buffer);
_AX = x;
_hex (_AH); // upper byte
_AX = x;
_hex (_AL); // lower byte
hex_buffer[4] = 0;
return hex_buffer;
}
char *byte (BYTE x)
{
_ES = FP_SEG (hex_buffer);
_DI = FP_OFF (hex_buffer);
_AL = x;
_hex (_AL); // upper byte
hex_buffer[2] = 0;
return hex_buffer;
}
void _hex (WORD x)
{
_AX = x;
asm {
mov ah, al
and al, 0fh
mov cl, 4
shr ah, cl
// ah has MSD
// al has LSD
or ax, 3030h
xchg al, ah
cmp ah, 39h
ja _fix_ah
}
_fix_ah_ret:
asm {
cmp al, 39h
ja _fix_al
}
write_it:
asm {
stosw
jmp hex_done
}
_fix_al:
asm {
sub al, 30h
add al, 'A' - 10
jmp write_it
}
_fix_ah:
asm {
sub ah, 30h
add ah, 'A' - 10
jmp _fix_ah_ret
}
hex_done:
}
void jputs (char *s)
{
if (!verbose)
return;
while (*s)
{
_AL = *s;
geninterrupt (0x29); // DOS fast putchar
if (*s == '\n')
{
_AL = 13;
geninterrupt (0x29);
}
s++;
}
}
int unload (void)
{
WORD tsrpsp, code;
WORD far *p;
if (!is_there())
{
puts (init_not_loaded);
return 1;
}
_restorezero (); // "buckle up, this could be a rough ride!"
_AH = MY_ID;
_AL = UNLOAD_CMD;
geninterrupt (0x2F); // make TSR unhook it's vects
if (_AX != 0xFFFF)
{
code = _CX; // int vect that could not be unloaded
puts (init_e_unloading);
puts (byte (code));
ENDL();
_AX = 0x4C04;
geninterrupt (0x21); // exit out quick
}
tsrpsp = _BX;
p = MK_FP (tsrpsp, 0x0A); // Location the TSR returns to when unloaded.
// this location in a PSP usually points
// back to command.com who loaded it. We,
// however, are sneakier than DOS realizes and
// we make this location point back to us.
// (Well, let's rightfuly give credit to
// Mr. Schulman for this one) <grin>
p[0] = FP_OFF (back_here);
p[1] = FP_SEG (back_here);
_AH = 0x50; // UNDOC DOS Set PSP segment
_BX = tsrpsp;
geninterrupt (0x21); // make our TSR the current process
_AX = 0x4C00; // terminate current (TSR) process
geninterrupt (0x21); // "remember to keep your hands up and
// scream the whole way!"
// NOTE: we should never get here, but instead end up in back_here()
puts (init_hose_bad); // "Toto, we're not in Kansas anymore!"
return 0;
}
void _loadds back_here () // use _loadds since DOS has blown away our
// DS value.
{
// If we get here, then the TSR was successfully unloaded, and we should
// step out of our cock-pit and kiss the ground (or at least give thanks
// to the DOS gods. Sacrafice a diskette or something. <double grin> )
// and now for something completely different, we mu